package com.lenovo.leos.filebrowser.engine.model;

import java.io.FileNotFoundException;
import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import android.util.Log;

import com.lenovo.leos.filebrowser.engine.model.FileIndex.Indexs;

public class FileIndexProvider extends ContentProvider {

        private static final String TAG = "FileIndexProvider";

        // private SQLiteDatabase sqlDB;

        private static final String DATABASE_NAME = "FileInterface.db";
        private static final int DATABASE_VERSION = 3;
        private static final String TABLE_NAME = "fileindex";

        private static HashMap<String, String> sIndexProjectionMap;

        private static final int INDEXS = 1;
        private static final int INDEX_ID = 2;
        private static final int DELETE_ID = 3;
        private static final int UPDATE_ID = 4;

        private static final UriMatcher sUriMatcher;

        private static class DatabaseHelper extends SQLiteOpenHelper {

                public DatabaseHelper(Context context) {
                        super(context, DATABASE_NAME, null, DATABASE_VERSION);
                }

                @Override
                public void onCreate(SQLiteDatabase db) {
                        db.execSQL("create table  " + TABLE_NAME + " ( "
                                        + FileIndex.Indexs._ID+ " integer primary key autoincrement, "
                                        + FileIndex.Indexs.DATA + " text, "
                                        + FileIndex.Indexs.SIZE+ " integer, " 
                                        + FileIndex.Indexs.DISPLAY_NAME + " text, "
                                        + FileIndex.Indexs.MIME_TYPE + " text, "
                                        + FileIndex.Indexs.OVERRIDE + " boolean " + ");");
                        Log.d(TAG, "create database and table");
                }

                @Override
                public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                                        + newVersion + ", which will destroy all old data");
                        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
                        onCreate(db);
                }

        }

        @Override
        public boolean onCreate() {
                DatabaseHelper dbHelper = new DatabaseHelper(getContext());
                return (null == dbHelper) ? false : true;
        }

        @Override
        public int delete(Uri uri, String where, String[] whereArgs) {
                Log.d(TAG, "delete function");
                DatabaseHelper dbHelper = new DatabaseHelper(getContext());
                if (dbHelper == null) {
                        throw new UnsupportedOperationException("Unknown URI: " + uri);
                }
                SQLiteDatabase sqlDB = dbHelper.getWritableDatabase();
                int count = 0;

                switch (sUriMatcher.match(uri)) {
                case INDEXS:
                        count = sqlDB.delete(TABLE_NAME, where, whereArgs);
                        break;

                case INDEX_ID:
                        String indexId = uri.getPathSegments().get(1);

                        count = sqlDB.delete(TABLE_NAME,
                                        Indexs._ID + "=" + indexId + (!TextUtils.isEmpty(where) ? " AND (" + where
                                                                        + ')' : ""), whereArgs);

                        break;
                case DELETE_ID:
                        String wherearg = uri.getPathSegments().get(2);

                        if (wherearg != null) {
                                String delSQL = "delete from " + TABLE_NAME + " where " + where
                                                + "=" + "'" + wherearg + "'";
                                sqlDB.execSQL(delSQL);
                                
                        }
                        break;

                default:
                        throw new IllegalArgumentException("Unknown URI " + uri);
                }
                getContext().getContentResolver().notifyChange(uri, null);
                dbHelper.close();
                return count;
        }

        @Override
        public String getType(Uri uri) {
                switch (sUriMatcher.match(uri)) {
                case INDEXS:
                        return Indexs.CONTENT_TYPE;

                case INDEX_ID:
                        return Indexs.CONTENT_ITEM_TYPE;

                default:
                        throw new IllegalArgumentException("Unknown URI " + uri);
                }
        }

        @Override
        public Uri insert(Uri uri, ContentValues initialValues) {
                Log.d(TAG, "insert function");
                long rowId = 0;
                ContentValues values;
                DatabaseHelper dbHelper = new DatabaseHelper(getContext());
                SQLiteDatabase sqlDB = dbHelper.getWritableDatabase();
                if (sUriMatcher.match(uri) != INDEXS) {
                        throw new IllegalArgumentException("Unknown URI " + uri);
                }

                if (initialValues != null) {
                        values = new ContentValues(initialValues);
                } else {
                        values = new ContentValues();
                }
                if (values.containsKey(FileIndex.Indexs.DATA) == false) {
                        values.put(FileIndex.Indexs.DATA, "");
                }
                Cursor c = sqlDB.query(TABLE_NAME, null, null, null, null, null, null);
                if (c.getCount() > 50 ){
              sqlDB.delete(TABLE_NAME, null, null);        
                }
                c.close();
                rowId = sqlDB.insert(TABLE_NAME, null, values);

                Log.d(TAG, "this is in fileprovider insert function id= " + rowId);
                Log.d(TAG, "index URI before building =" + uri.toString());
                if (rowId > 0) {
                        Log.d(TAG, "rowId > 0");
                        Uri newUri = ContentUris.appendId(
                                        FileIndex.Indexs.CONTENT_URI.buildUpon(), rowId).build();
                        if (newUri != null) {
                                getContext().getContentResolver().notifyChange(newUri, null);
                        }
                        Log.d(TAG, "index URI =" + newUri.toString());
                        dbHelper.close();
                        return newUri;
                }
                throw new SQLException("Failed to insert row into " + uri);
        }

        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
                Log.d(TAG, "query function");

                DatabaseHelper dbHelper = new DatabaseHelper(getContext());
                if (dbHelper == null) {
                        return null;
                }
                SQLiteDatabase sqlDB = dbHelper.getReadableDatabase();
                SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
                String groupBy = null;
                String orderBy = null;
                String limit = uri.getQueryParameter("limit");
                Log.d(TAG, "this is in provider query uri=" + uri.toString());
                Log.d(TAG, "this is in provider query select=" + selection);

                switch (sUriMatcher.match(uri)) {
                case INDEXS:

                        qb.setTables(TABLE_NAME);
                        if (uri.getQueryParameter("distinct") != null)
                                qb.setDistinct(true);
                        // qb.setProjectionMap(sIndexProjectionMap);
                        break;

                case INDEX_ID:
                        // Log.d(TAG, "this is in INDEX_ID query index_id="+
                        // uri.getPathSegments().get(1));
                        qb.setTables(TABLE_NAME);
                        if (uri.getQueryParameter("distinct") != null)
                                qb.setDistinct(true);
                        // qb.setProjectionMap(sIndexProjectionMap);
                        qb.appendWhere(FileIndex.Indexs._ID + "="
                                        + uri.getPathSegments().get(1));
                        Log.d(TAG, "this is in INDEX_ID query index_id="
                                        + uri.getLastPathSegment());
                        break;

                default:
                        throw new IllegalArgumentException("Unknown URI " + uri);
                }

                // If no sort order is specified use the default

                if (TextUtils.isEmpty(sortOrder)) {
                        orderBy = FileIndex.Indexs.DEFAULT_SORT_ORDER;
                } else {
                        orderBy = sortOrder;
                }

                // Get the database and run the query

                Log.d(TAG, "next clause is query ui=" + uri.toString());
                Cursor c = qb.query(sqlDB, projection, selection, selectionArgs,
                                groupBy, null, orderBy, limit);
                Log.d(TAG, "query done");
                
                // Tell the cursor what uri to watch, so it knows when its source data
                // changes
                if (null != c) {
                        c.setNotificationUri(getContext().getContentResolver(), uri);
                }
                return c;
        }

        @Override
        public int update(Uri uri, ContentValues values, String where,
                        String[] whereArgs) {
                Log.d(TAG, "update function");
                DatabaseHelper dbHelper = new DatabaseHelper(getContext());
                if (dbHelper == null) {
                        throw new UnsupportedOperationException("Unknown URI: " + uri);
                }
                SQLiteDatabase sqlDB = dbHelper.getWritableDatabase();
                ContentValues initialValues = new ContentValues(values);
                int count;
                switch (sUriMatcher.match(uri)) {
                case INDEXS:
                        count = sqlDB.update(TABLE_NAME, initialValues, where, whereArgs);
                        break;

                case INDEX_ID:
                        String indexId = uri.getPathSegments().get(1);
                        count = sqlDB.update(TABLE_NAME, values,
                                        Indexs._ID + "=" + indexId + (!TextUtils.isEmpty(where) ? " AND (" + where
                                                                        + ')' : ""), whereArgs);
                        break;

                default:
                        throw new IllegalArgumentException("Unknown URI " + uri);
                }

                getContext().getContentResolver().notifyChange(uri, null);
                dbHelper.close();
                return count;
        }

        @Override
        public ParcelFileDescriptor openFile(Uri uri, String mode)
                        throws FileNotFoundException {

                Log.d(TAG, "this is in openfile, uri=" + uri.toString());
                ParcelFileDescriptor pfd = openFileHelper(uri, "r");
                return pfd;
        }

        static {
                sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
                sUriMatcher.addURI(FileIndex.AUTHORITY, "fileindex", INDEXS);
                sUriMatcher.addURI(FileIndex.AUTHORITY, "fileindex/#", INDEX_ID);
                sUriMatcher.addURI(FileIndex.AUTHORITY, "fileindex/delete/*", DELETE_ID);
                sUriMatcher.addURI(FileIndex.AUTHORITY,"fileindex/update/uri/*/filepath/*", UPDATE_ID);

                sIndexProjectionMap = new HashMap<String, String>();
                sIndexProjectionMap.put(Indexs._ID, Indexs._ID);
                sIndexProjectionMap.put(FileIndex.Indexs.DATA, FileIndex.Indexs.DATA);

        }

}
